#if OPENSSL_WINRT_DESKTOP || OPENSSL_WINRT_PHONE

#include "RandomManager.h"

using Windows::Foundation::GetActivationFactory;
using ABI::Windows::Storage::Streams::IBuffer;
using Microsoft::WRL::Wrappers::HStringReference;


RandomManager* RandomManager::randomManager;

RandomManager::RandomManager()
{
	::RoInitialize(RO_INIT_MULTITHREADED);
	//Must not fail
	HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Security_Cryptography_CryptographicBuffer).Get(), &cryptographicBuffer);
	if (FAILED(hr))
		throw hr;
}

RandomManager* RandomManager::GetRandomManager()
{
	if (nullptr == randomManager)
		randomManager = new RandomManager();
	return randomManager;
}

void RandomManager::GenerateRandomBytes(BYTE* randBuffer, int length)
{
	ComPtr<IBuffer> buffer;
	this->cryptographicBuffer->GenerateRandom((UINT32)length, &buffer);
	HSTRING encodedBuffer = nullptr;
	this->cryptographicBuffer->EncodeToHexString(*buffer.GetAddressOf(), &encodedBuffer);
	PCWSTR rawString = ::WindowsGetStringRawBuffer(encodedBuffer, nullptr);
	::wcstombs((char*)randBuffer, rawString, length);
	::WindowsDeleteString(encodedBuffer);
}

int RandomManager::GenerateRandomNumber()
{
	UINT32 num = 0;
	this->cryptographicBuffer->GenerateRandomNumber(&num);
	return num;
}

#endif	//OPENSSL_WINRT_DESKTOP || OPENSSL_WINRT_PHONE

